﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using OxyPlot;
using OxyPlot.Xps;

namespace DesicionTreeViewer
{
    //объект для работы с прямой
    public class ClassificationLine : OxyPlot.LineAnnotation
    {
        private bool isMouseDown;
        private DataPoint mouseDownPoint;
        private DataPoint prevMouuseMovePoint;

        public ClassificationLine Clone()
        {
            var clone = new ClassificationLine
            {
                Slope = this.Slope,
                Intercept = this.Intercept,
                Type = this.Type,
                Text = this.Text
            };
            return clone;
        }

        public ClassificationLine()
        {
            this.Type = LineAnnotationType.LinearEquation;
            this.Slope = 1;
            this.Intercept = 0;
        }

        //лежит ли точка под прямой
        public bool IsUnderLine(DataPoint point)
        {
            return (Slope * point.X + Intercept) > point.Y;
        }

        protected override void OnMouseDown(object sender, OxyMouseEventArgs e)
        {
            isMouseDown = true;
            mouseDownPoint = this.InverseTransform(e.Position);
            prevMouuseMovePoint = mouseDownPoint;
            e.Handled = true;
        }

        protected override void OnMouseMove(object sender, OxyMouseEventArgs e)
        {
            if (isMouseDown)
            {
                DataPoint thePoint = this.InverseTransform(e.Position);
                if (!e.IsShiftDown)
                {
                    Intercept = thePoint.Y - Slope * thePoint.X;
                }
                else
                {
                    DataPoint normalVector = new DataPoint(-Slope, 1);
                    DataPoint rotatedNormalVector = normalVector;

                    //угол поворота
                    double teta = 0;

                    if (thePoint.Y > prevMouuseMovePoint.Y)
                    {
                        //поварачиваем по часовой стрелке
                        teta += 0.01;
                    }
                    else
                    {
                        //поварачиваем против часовой стрелки
                        teta -= 0.01;

                    }


                    rotatedNormalVector.X = Math.Cos(teta) * (normalVector.X) + Math.Sin(teta) * (normalVector.Y);
                    rotatedNormalVector.Y = -Math.Sin(teta) * (normalVector.X) + Math.Cos(teta) * (normalVector.Y);

                    double vectorNorm = Math.Sqrt(rotatedNormalVector.X * rotatedNormalVector.X + rotatedNormalVector.Y * rotatedNormalVector.Y);
                    rotatedNormalVector.X /= vectorNorm;
                    rotatedNormalVector.Y /= vectorNorm;

                    double newIntercept = -rotatedNormalVector.X * mouseDownPoint.X - rotatedNormalVector.Y * mouseDownPoint.Y;
                    Slope = -rotatedNormalVector.X / rotatedNormalVector.Y;
                    Intercept = -newIntercept / rotatedNormalVector.Y;
                    this.Type = LineAnnotationType.LinearEquation;
                }

                prevMouuseMovePoint = this.InverseTransform(e.Position);

                updateText();
                this.PlotModel.RefreshPlot(true);
            }
        }
      
        protected override void OnMouseUp(object sender, OxyMouseEventArgs e)
        {
            isMouseDown = false;
            this.PlotModel.RefreshPlot(true);
        }

        private void updateText()
        {
            this.Text = "y = " + (Math.Round(this.Slope, 3)).ToString() + " * x + " + (Math.Round(this.Intercept, 3)).ToString();
        }

    }
}
